package util;


import java.text.MessageFormat;
import java.util.Locale;

import log.Log;
import log.Logger;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.MessageSourceResolvable;

/**
 * SpringContextHelper提供操作Spring ApplicationContext的相关方法
 * 
 * @author:
 *          唐竹
 * @date
 *       创建时间：2011-6-2 下午09:20:44
 */
public class SpringContextHelper implements ApplicationContextAware {
	private static Logger logger = Log.get(SpringContextHelper.class);
	/**
	 * Spring ApplicationContext
	 */
	private static ApplicationContext context;
	/**
	 * 语言环境
	 */
	private static Locale locale = Locale.CHINA;

	public void setApplicationContext(ApplicationContext context) throws BeansException {
		// TODO Auto-generated method stub
		SpringContextHelper.context = context;
		logger.info("Sett Application Context:{}", context.toString());
	}

	/**
	 * 检查context是否被注入
	 * 
	 * @throws IllegalStateException
	 *             - 当context为null时抛出，这时你需要检查SpringContextHelper是否配置
	 * @log
	 *      <YYYY-MM-DD 变更者 变更内容>
	 *      2011-6-8 唐竹 创建
	 */
	private static void contextState() {
		if (context == null) {
			throw new IllegalStateException(
					"Spring context not set in SpringContextHelper. Please check jaf-core-context.xml is load?");
		}
	}

	/**
	 * 获得Spring容器中的bean，调用SpringContext的getBean方法并Catch异常时返回null
	 * 
	 * @param beanName
	 *            Bean的名称，不能为空或者null
	 * @return
	 *         B 返回Spring容器中的Bean，找不到时返回null
	 * @throws IllegalStateException
	 *             - 当context为null时抛出，这时你需要检查SpringContextHelper是否配置<br>
	 *             IllegalArgumentException - 当beanName为null时抛出
	 * @log
	 *      <YYYY-MM-DD 变更者 变更内容>
	 *      2011-6-2 唐竹 创建
	 */
	@SuppressWarnings("unchecked")
	public static <B> B getBean(String beanName) {
		AssertUtils.notEmpty(beanName, "Bean name not should be null!");
		contextState();
		B bean = null;
		try {
			bean = (B) context.getBean(beanName);
		} catch (BeansException e) {
			// TODO Auto-generated catch block
			Object[] param = new Object[] { beanName, e };
			logger.error("The bean[{}] which in spring context not found! Cause by: {}", param);
		}
		return bean;
	}

	/**
	 * 获得您的message信息
	 * 
	 * @param code
	 *            在message.properties文件中的key，code不能为null
	 * @param args
	 *            替换message中取代符中的内容
	 * @throws IllegalStateException
	 *             当context为null时抛出，这时你需要检查SpringContextHelper是否配置<br>
	 * @return
	 *         String
	 * @log
	 *      <YYYY-MM-DD 变更者 变更内容>
	 *      2011-6-2 唐竹 创建
	 */
	public static String getMessage(String code, Object... args) {
		if (context != null)
			return filterMessage(context.getMessage(code, args, getDefaultMessage(code), locale));
		logger.warn("Spring context not set in SpringContextHelper. Please check jaf-core-context.xml is load?");
		return filterMessage(MessageFormat.format(getDefaultMessage(code), args));
	}

	/**
	 * 获得您的message信息
	 * 
	 * @param code
	 *            在message.properties文件中的key，为null时使用MessageFormat格式化defaultMessage
	 * @param defaultMessage
	 *            默认信息
	 * @param args
	 *            替换message中取代符中的内容
	 * @return
	 *         String
	 * @throws IllegalStateException
	 *             当context为null时抛出，这时你需要检查SpringContextHelper是否配置<br>
	 * @log
	 *      <YYYY-MM-DD 变更者 变更内容>
	 *      2011-7-7 唐竹 创建
	 */
	public static String getMessage(String code, String defaultMessage, Object... args) {
		if (context != null)
			return filterMessage(context.getMessage(code, args, defaultMessage, locale));
		logger.warn("Spring context not set in SpringContextHelper. Please check jaf-core-context.xml is load?");
		return filterMessage(MessageFormat.format(defaultMessage, args));
	}

	/**
	 * 获得您的message信息
	 * 
	 * @param resolvable
	 *            错误信息
	 * @return
	 *         String
	 * @throws IllegalStateException
	 *             - 当context为null时抛出，这时你需要检查SpringContextHelper是否配置<br>
	 * @log
	 *      <YYYY-MM-DD 变更者 变更内容>
	 *      2011-6-2 唐竹 创建
	 */
	public static String getMessage(MessageSourceResolvable resolvable) {
		if (context != null)
			return filterMessage(context.getMessage(resolvable, locale));
		logger.warn("Spring context not set in SpringContextHelper. Please check jaf-core-context.xml is load?");
		return "Unknow Exception";
	}

	/**
	 * 删除message中的花括号
	 * 
	 * @param message
	 * @return
	 *         String
	 * @log
	 *      <YYYY-MM-DD 变更者 变更内容>
	 *      2011-6-2 唐竹 创建
	 */
	private static String filterMessage(String message) {
		return message.replaceAll("\\{[^{]+\\}", "");
	}

	/**
	 * 当没有查找到message时使用该方法获得默认信息
	 * 
	 * @param code
	 * @return
	 *         String
	 * @log
	 *      <YYYY-MM-DD 变更者 变更内容>
	 *      2011-6-2 唐竹 创建
	 */
	public static String getDefaultMessage(String code) {
		StringBuffer sb = new StringBuffer().append('[').append(code).append("]Undefined");
		return sb.toString();
	}
}

